package xyz.labmem.main.application.controller.api.sys.authority;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import xyz.labmem.main.annotation.RoleValid;
import xyz.labmem.main.application.controller.api.sys.authority.request.RoleValidListRequest;
import xyz.labmem.main.application.controller.api.sys.authority.request.RoleValidRequest;
import xyz.labmem.main.application.entity.sys.Role;
import xyz.labmem.main.application.mapper.sys.RoleMapper;
import xyz.labmem.main.result.ResultUtil;
import xyz.labmem.main.result.ResultVo;
import xyz.labmem.main.sys.StaticVariable;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author ：刘天予
 * @date ：Created in 2020/5/8 11:07
 * @description：权限
 */
@RestController
@Api(tags = "后台菜单API")
@RequestMapping("/admin/authorityApi/api")
public class AuthorityValidApi extends StaticVariable {

    private final RoleMapper roleMapper;

    public AuthorityValidApi(RoleMapper roleMapper) {
        this.roleMapper = roleMapper;
    }

    /**
     * @return
     */
    @PostMapping("/list")
    @RoleValid
    @ApiOperation("接口列表")
    public ResultVo authorityList(@RequestBody RoleValidListRequest request) {

        LambdaQueryWrapper<xyz.labmem.main.application.entity.sys.RoleValid> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        String comment = request.getComment();
        if (StrUtil.isNotEmpty(comment)) {
            lambdaQueryWrapper.like(xyz.labmem.main.application.entity.sys.RoleValid::getComment, comment);
        }
        String className = request.getClassName();
        if (StrUtil.isNotEmpty(className)) {
            lambdaQueryWrapper.like(xyz.labmem.main.application.entity.sys.RoleValid::getClassName, className);
        }
        String methodName = request.getMethodName();
        if (StrUtil.isNotEmpty(methodName)) {
            lambdaQueryWrapper.like(xyz.labmem.main.application.entity.sys.RoleValid::getMethodName, methodName);
        }
        Integer isApi = request.getIsApi();
        if (isApi != null) {
            lambdaQueryWrapper.eq(xyz.labmem.main.application.entity.sys.RoleValid::getIsApi, isApi);
        }
        lambdaQueryWrapper.orderByAsc(xyz.labmem.main.application.entity.sys.RoleValid::getClassName);
        List<xyz.labmem.main.application.entity.sys.RoleValid> newList = new ArrayList<>();
        IPage<xyz.labmem.main.application.entity.sys.RoleValid> RolePage =
                new xyz.labmem.main.application.entity.sys.RoleValid().selectPage(request.getPage(), lambdaQueryWrapper);
        RolePage.getRecords().forEach(r -> {
            if (StrUtil.isNotEmpty(r.getRoleList())) {
                JSONArray RoleList = JSONArray.parseArray(r.getRoleList());
                if (RoleList.size() > 0) {
                    StringBuilder RoleId = new StringBuilder();
                    StringBuilder RoleName = new StringBuilder();
                    new Role().selectList(new LambdaQueryWrapper<Role>().in(Role::getRoleEnum, RoleList)).forEach(e -> {
                        RoleId.append(e.getId()).append(",");
                        RoleName.append(e.getRoleName()).append(",");
                    });
                    r.setRoleList(RoleId.toString());
                    r.setRoleName(RoleName.toString());
                }
            }
            newList.add(r);
        });
        RolePage.setRecords(newList);
        return ResultUtil.page(RolePage);
    }

    /**
     * 修改权限角色
     *
     * @return
     */
    @PostMapping("/update")
    @RoleValid
    @ApiOperation("修改权限角色")
    public ResultVo update(@RequestBody xyz.labmem.main.application.entity.sys.RoleValid roleValid) {
        String roleList = roleValid.getRoleList();
        if (StrUtil.isNotEmpty(roleList)) {
            JSONArray roleEnumList = new JSONArray();
            JSONArray RoleList = JSONArray.parseArray(roleList);
            List<String> list = RoleList.toJavaList(String.class);
            roleMapper.selectBatchIds(list).forEach(r -> roleEnumList.add(r.getRoleEnum()));
            roleValid.setRoleList(roleEnumList.toJSONString());
        } else
            roleValid.setRoleList(new JSONArray().toJSONString());
        if (roleValid.updateById())
            return ResultUtil.success();
        return ResultUtil.failed();
    }

    /**
     * 批量所有API权限角色
     *
     * @return
     */
    @PostMapping("/batchUpdate")
    @RoleValid
    @ApiOperation("批量修改权限角色")
    public ResultVo updateApiAll(@RequestBody RoleValidRequest request) {
        try {
            xyz.labmem.main.application.entity.sys.RoleValid roleValid = new xyz.labmem.main.application.entity.sys.RoleValid();
            JSONArray roleEnumList = new JSONArray();
            JSONArray RoleList = JSONArray.parseArray(request.getRoleList());
            List<String> list = RoleList.toJavaList(String.class);
            roleMapper.selectBatchIds(list).forEach(r -> roleEnumList.add(r.getRoleEnum()));

            LambdaQueryWrapper<xyz.labmem.main.application.entity.sys.RoleValid> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            if (request.getChange().equals("all")) {
                JSONObject where = JSONObject.parseObject(request.getWhere());
                String comment = where.getString("comment");
                if (StrUtil.isNotEmpty(comment)) {
                    lambdaQueryWrapper.like(xyz.labmem.main.application.entity.sys.RoleValid::getComment, comment);
                }
                String className = where.getString("className");
                if (StrUtil.isNotEmpty(className)) {
                    lambdaQueryWrapper.like(xyz.labmem.main.application.entity.sys.RoleValid::getClassName, className);
                }
                String methodName = where.getString("methodName");
                if (StrUtil.isNotEmpty(methodName)) {
                    lambdaQueryWrapper.like(xyz.labmem.main.application.entity.sys.RoleValid::getMethodName, methodName);
                }
                Integer isApi = where.getInteger("isApi");
                if (isApi != null) {
                    lambdaQueryWrapper.eq(xyz.labmem.main.application.entity.sys.RoleValid::getIsApi, isApi);
                }
            } else {
                JSONArray array = JSONArray.parseArray(request.getWhere());
                List<String> idList = array.toJavaList(String.class);
                lambdaQueryWrapper.in(xyz.labmem.main.application.entity.sys.RoleValid::getId, idList);
            }

            roleValid.selectList(lambdaQueryWrapper).forEach(r -> {
                JSONArray rl = JSONArray.parseArray(r.getRoleList());
                Set<String> roleSet = new HashSet<>(rl.toJavaList(String.class));
                if (request.getType() == 1)
                    roleSet.addAll(roleEnumList.toJavaList(String.class));
                else
                    roleSet.removeAll(roleEnumList.toJavaList(String.class));
                r.setRoleList(JSONArray.parseArray(JSONObject.toJSONString(roleSet)).toJSONString());
                r.updateById();
            });
            return ResultUtil.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.failed();
        }
    }

    /**
     * 修改权限角色
     *
     * @return
     */
    @PostMapping("/reload")
    @RoleValid
    @ApiOperation("重载权限配置")
    public ResultVo reloadValid() {
        try {
            new xyz.labmem.main.application.entity.sys.RoleValid().selectAll().parallelStream().forEach(r ->
                    RoleValidEntities.put(r.getClassName() + "." + r.getMethodName(), r.getRoleList())
            );
            return ResultUtil.success();
        } catch (Exception e) {
            return ResultUtil.failed();
        }
    }


}
